import axios, { AxiosRequestConfig, CancelTokenSource, AxiosResponse } from "axios";
import axiosInstance from "./index";
import {
  currentRequestQueue
} from "./interceptors";
import {
  cloneDeep
} from "lodash-es";

// 缓存请求canceltoken
const cancelTokenMap = new Map<string, CancelTokenSource>();

/**
 * 获取取消请求token
 *
 * @param {string} key
 * @return {*}
 */
export const getCancelToken = (key: string, config: AxiosRequestConfig) => {
  const source = axios.CancelToken.source();
  cancelTokenMap.set(key, source);
  requestConfigMap.set(key, cloneDeep(config));
  return source.token;
};

/**
 * 取消指定请求
 *
 * @param {string} key 请求hash
 */
export const cancel = (key: string) => {
  const source = cancelTokenMap.get(key);
  cancelTokenMap.delete(key);
  source && source.cancel(key);
};

/**
 * 取消所有请求
 *
 */
export const cancelAll = () => {
  for (const key of cancelTokenMap.keys()) {
    cancel(key);
  }
};

// 缓存待重发的请求配置
const requestConfigMap = new Map<string, AxiosRequestConfig>();

// 缓存待重发的请求
// eslint-disable-next-line
const resolveMap = new Map<string, () => void>();
/**
 * 请求重发
 *
 * @param {string} key
 */
export const resend = (key: string) => {
  const resolve = resolveMap.get(key);
  resolve && resolve();
  resolveMap.delete(key);
  requestConfigMap.delete(key);
};

/**
 * 重发所有请求
 *
 */
export const resendAll = () => {
  for (const key of requestConfigMap.keys()) {
    resend(key);
  }
};

/**
 * 等待重发已取消的请求
 *
 * @param {string} key
 */
export const waitResendCanceledRequest = (hash: string) => {
  const keyIndex = currentRequestQueue.indexOf(hash);
  keyIndex !== -1 && currentRequestQueue.splice(keyIndex, 1);
  // @ts-ignore
  let promiseResolve: (value: any) => void = null;
  const cancelPromise = new Promise<AxiosResponse<Api.ResponseOptions>>(resolve =>
    promiseResolve = resolve
  );
  console.error("请求取消 => " + hash);
  const config = requestConfigMap.get(hash);
  // @ts-ignore
  resolveMap.set(hash, () => promiseResolve(axiosInstance(config)));
  return cancelPromise;
};
